import { typeOf, ObjectOwn } from '@/utils/tools'

import { Parser } from 'expr-eval'

/**
 * 转化函数 将原数据 转化成统一字段
 * @param {content}
 * @return {content}
 */
export const convert = (content) => {
  return content.map((v) => {
    v.list = v.list.map((w) => {
      return {
        id: w.id,
        attr: {},
        subTitle: w.subTitle,
        name: w.questionName,
        type: w.questionType,
        sort: w.sort,
        inputText: w.inputText,
        inputMode: w.inputMode,
        rules: w.rules,
        config: w.config,
        scale: false,
        options: w.options.map((v) => {
          v['scale'] = false
          return v
        }),
        value: w.value,
        showCondition: w.showCondition || null,
        exc: w.exc ? JSON.parse(w.exc) : {},
        relationQuestionCode: w.relationQuestionCode,
        questionSource: w.questionSource,
        relationQuestionId: w.relationQuestionId,
        extContent: w.type === '搜索输入' && w.extContent ? JSON.parse(w.extContent) : w.extContent
      }
    })
    return v
  })
}

const operatorMaps = {
  '===': '==',
  '>': '>',
  '>=': '>=',
  '<': '<',
  '<=': '<=',
  '!==': '!='
}

const transform = (obj) => {
  const parser = new Parser()
  //   console.log(parser)
  if (typeOf(obj.value) === 'string') {
    return parser.parse('x ' + operatorMaps[obj.operator] + ' "' + obj.value + '"')
  } else {
    return parser.parse('x ' + operatorMaps[obj.operator] + ' ' + obj.value)
  }
}

const transformCustom = (str, obj) => {
  const s = str.replace(/\$\{(.*?)\}/g, (_, key) => {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      return obj[key].value
    } else {
      throw new Error('自定义条件执行异常找不到变量')
    }
  })
  const parser = new Parser()
  const f = parser.parse(s)
  // const f = new Function('x', 'console.log(1)')
  return f.evaluate()
}

const loop = (obj, d) => {
  if (obj.operator === 'AND') {
    return obj.conditions.every((v) => {
      if (v.operator !== 'AND' && v.operator !== 'OR') {
        if (v.operator === '填写完成') {
          return d[v.id].value.trim() !== ''
        } else {
          // console.log(v)
          if (v.id === 'custom') {
            return transformCustom(v.value, d)
          } else if (d[v.id].type.includes('单选')) {
            return d[v.id].sort == v.value
          } else if (d[v.id].type.includes('多选')) {
            return d[v.id].sort.includes(v.value)
          } else if (d[v.id].type === '数字选择') {
            const f = transform(v)
            return f.evaluate({ x: d[v.id].value })
          } else if (d[v.id].type === '输入') {
            const f = transform(v)
            return f.evaluate({ x: d[v.id].value })
          }
          if (typeOf(d[v.id].value) === 'string') {
            return d[v.id].value.trim() !== ''
          } else if (typeOf(d[v.id].value) === 'array') {
            return d[v.id].value.length > 0
          } else {
            return true
          }
          // return f(d[v.id].value)
        }
      } else {
        return loop(v, d)
      }
    })
  } else if (obj.operator === 'OR') {
    return obj.conditions.some((v) => {
      if (v.operator !== 'AND' && v.operator !== 'OR') {
        if (v.operator === '填写完成') {
          if (['多选', '多选+输入', '图片上传'].includes(d[v.id].type)) {
            return d[v.id].value.length
          } else {
            return d[v.id].value.trim() !== ''
          }
        } else {
          if (v.id === 'custom') {
            return transformCustom(v.value, d)
          } else if (d[v.id].type.includes('单选')) {
            return d[v.id].sort == v.value
          } else if (d[v.id].type.includes('多选')) {
            return d[v.id].sort.includes(v.value)
          } else if (d[v.id].type === '数字选择') {
            const f = transform(v)
            return f.evaluate({ x: d[v.id].value })
          } else if (d[v.id].type === '输入') {
            const f = transform(v)
            return f.evaluate({ x: d[v.id].value })
          }
          if (typeOf(d[v.id].value) === 'string') {
            return d[v.id].value.trim() !== ''
          } else if (typeOf(d[v.id].value) === 'array') {
            return d[v.id].value.length > 0
          } else {
            return true
          }
          // return f(d[v.id].value)
        }
      } else {
        return loop(v, d)
      }
    })
  }
  return true
}

/**
 * 返回经过筛选后的数组 传入问卷的content
 * @param {list}
 * @return {list}
 */
export const showCondition = (arr) => {
  const obj = {}
  arr.map((v) => {
    v.list.map((u) => {
      obj[u.id] = u
    })
  })

  const List = []

  for (const v of arr) {
    const L = v.list.filter((u) => {
      if (!u.showCondition) {
        return true
      }
      let show = true
      if (u.showCondition.hasOwnProperty('show')) {
        show = u.showCondition.show
      }
      let r
      try {
        r = loop(u.showCondition, obj)
      } catch (e) {
        throw new Error(`自定义条件执行异常，异常问题：${u.name}`)
      }
      if (show) {
        return r
      } else {
        return !r
      }
    })
    if (L.length) {
      List.push({
        ...v,
        list: L
      })
    }
  }

  setAttr(List)

  return List
}

export const setAttr = (content) => {
  content.map((v) => {
    v.list.map((item) => {
      item.attr = {}
    })
  })

  content.map((v) => {
    v.list.map((item, index) => {
      if (
        ObjectOwn(item.exc, 'direction') &&
        item.exc.direction === 'row' &&
        index > 0 &&
        v.list[index - 1].exc.direction === 'row'
      ) {
        if (ObjectOwn(item.attr, 'class') && item.attr.class) {
          item.attr.class.push('after')
        } else {
          item.attr['class'] = ['after']
        }
        item.attr['hr'] = true
      }
      if (
        ObjectOwn(item.exc, 'direction') &&
        item.exc.direction === 'row' &&
        index < v.list.length - 1 &&
        ObjectOwn(v.list[index + 1].exc, 'direction') &&
        v.list[index + 1].exc.direction === 'row'
      ) {
        if (ObjectOwn(item.attr, 'class') && item.attr.class) {
          item.attr.class.push('before')
        } else {
          item.attr['class'] = ['before']
        }
      }
      if (
        ObjectOwn(item.exc, 'subTitle') &&
        item.exc.subTitle &&
        index < v.list.length - 1 &&
        (!ObjectOwn(v.list[index + 1].attr, 'subTitle') || !v.list[index + 1].exc.subTitle)
      ) {
        if (ObjectOwn(item.attr, 'class') && item.attr.class) {
          if (!item.attr.class.incldues('before')) {
            item.attr.class.push('before')
          }
        } else {
          item.attr['class'] = ['before']
        }
        item.attr.subTitle = item.exc.subTitle
      }
      if (
        index > 0 &&
        !item.exc.subTitle &&
        ObjectOwn(v.list[index - 1].attr, 'subTitle') &&
        v.list[index - 1].attr.subTitle
      ) {
        if (ObjectOwn(item.attr, 'class') && item.attr.class) {
          if (!item.attr.class.incldues('after')) {
            item.attr.class.push('after')
          }
        } else {
          item.attr['class'] = ['after']
        }
        item.attr.subTitle = item.exc.subTitle
        item.attr['hr'] = true
        if (index < v.list.length - 1 && v.list[index + 1].attr.subTitle) {
          if (!item.attr.class.incldues('before')) {
            item.attr.class.push('before')
          }
        }
      }
    })
  })
}

/**
 * 根据cid查找到当前元素的位置 传入问卷的content和当前元素的id
 * @param {list}
 * @return {item, indexs, next, before} //item 当前元素, indexs 当前元素序号数组 例[1,1], next 下一个元素, before 上一个元素
 */
export const next = (arr, cId) => {
  let item = null
  let indexs = []
  let bIndex = []
  let nIndex = []
  let c = 0
  arr.find((v, i) => {
    return v.list.find((u, j) => {
      if (v.exc && Object.prototype.hasOwnProperty.call(v.exc, 'show') && !v.exc.show) {
        return false
      }
      if (c == 1) {
        c = 0
        nIndex = [i, j]
        return true
      } else if (u.id === cId) {
        item = u
        indexs = [i, j]
        c = 1
      } else {
        bIndex = [i, j]
      }
    })
  })
  let n = null
  if (nIndex.length) {
    n = arr[nIndex[0]].list[nIndex[1]]
  }
  // if (arr[indexs[0]].list.length - 1 > indexs[1]) {
  //   n = arr[indexs[0]].list[indexs[1] + 1]
  // } else if (arr.length - 1 > indexs[0]) {
  //   n = arr[indexs[0] + 1].list[0]
  // }
  let b = null
  if (bIndex.length) {
    b = arr[bIndex[0]].list[bIndex[1]]
  }
  return {
    item: item,
    indexs: indexs,
    before: b,
    bIndex: bIndex,
    next: n,
    nIndex: nIndex
  }
}

/**
 * 传入当前问题，返回校验结果
 * @param {item}
 * @return {code, status, item, message} // code：校验code 0成功 1失败 status 校验说明 success fail item 当前元素 message 文案
 */
export const validate = (item) => {
  const rules = item.rules
  if (!rules || typeOf(rules) !== 'array' || !rules.length) {
    return {
      code: 0,
      status: 'success',
      item: item,
      message: '校验通过'
    }
  }
  const c = rules.find((v) => {
    if (v.mode === 'required' && v.required) {
      if (
        (typeOf(item.value) === 'string' && !item.value.trim()) ||
        (typeOf(item.value) === 'number' && !(item.value || item.value === 0))
      ) {
        return true
      } else if (typeOf(item.value) === 'array') {
        if (!item.value.length) {
          return true
        } else {
          const f = item.options.findIndex((w) => {
            const i = item.value.findIndex((u) => {
              return u === w.value && w.input
            })
            if (i > -1) {
              return true
            }
          })
          if (f > -1 && !item.inputText.trim()) {
            return true
          } else {
            return false
          } 
        }
      }
    } else if (v.mode === 'number') {
      if (
        (typeOf(v.min) === 'string' &&
          v.min.length &&
          v.min.trim() &&
          Number(item.value) < v.min) ||
        (typeOf(v.min) === 'number' && Number(item.value) < v.min)
      ) {
        return true
      }
      if (
        (typeOf(v.max) === 'string' &&
          v.max.length &&
          v.max.trim() &&
          Number(item.value) > v.max) ||
        (typeOf(v.max) === 'number' && Number(item.value) > v.max)
      ) {
        return true
      }
    } else if (v.mode === 'regexp') {
      const reg = new RegExp(v.patternStr)
      if (!reg.test(item.value)) {
        return true
      }
    }
  })
  if (c) {
    return {
      code: 1,
      status: 'fail',
      item: item,
      message: c.message
    }
  } else {
    return {
      code: 0,
      status: 'success',
      item: item,
      message: '校验通过'
    }
  }
}

/**
 * 传入转化后的问题content。设置values
 * @param {List}
 */
export const fillValue = (List, values) => {
  const obj = {}
  values.map((v) => {
    const id = v.relationQuestionCode ? v.relationQuestionCode : v.questionId
    if (obj[id]) {
      obj[id] = [...obj[id], v]
    } else {
      obj[id] = [v]
    }
  })

  List.map((v) => {
    v.list.map((u) => {
      const id = u.relationQuestionCode ? u.relationQuestionCode : u.id
      if (obj[id]) {
        if (u.type.includes('单选')) {
          u.value = obj[id][0].content
          const s = u.options.find((w) => w.value === obj[id][0].content)
          u.sort = s ? s.sort : ''
        } else if (u.type === '输入') {
          u.value = obj[id][0].content
        } else if (u.type.includes('多选')) {
          u.value = obj[id].reduce((p, c) => {
            return [...p, c.content]
          }, [])
          u.sort = u.value
            .map((w) => {
              const i = u.options.find((z) => z.value === w)
              return i.sort
            })
            .filter((z) => z)
        } else if (u.type === '搜索输入') {
          u.value = obj[id][0].content
          u.extContent = obj[id][0].extContent ? JSON.parse(obj[id][0].extContent) : []
        } else {
          u.value = obj[id][0].content
        }
      }
    })
  })
}

// 计算总题目数
export const countLength = (List) => {
  return List.reduce((p, c) => {
    return p + c.list.length
  }, 0)
}

// 设置start
export const setStart = (List) => {
  let s = 0
  List.map((v, i) => {
    if (!i) {
      v['start'] = 0
    } else {
      v['start'] = s
    }
    v['Length'] = v.list.length
    s += v['Length']
  })
}
